package com.hfi.security.core.social;

import com.hfi.security.core.exception.ErrorCode;
import com.hfi.security.core.properties.SecurityConstants;
import com.hfi.security.core.properties.SecurityProperties;
import com.hfi.security.core.support.Response;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.security.web.DefaultRedirectStrategy;
import org.springframework.security.web.RedirectStrategy;
import org.springframework.security.web.savedrequest.HttpSessionRequestCache;
import org.springframework.security.web.savedrequest.RequestCache;
import org.springframework.security.web.savedrequest.SavedRequest;
import org.springframework.social.connect.Connection;
import org.springframework.social.connect.web.ProviderSignInUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.ServletWebRequest;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @author ChangLiang
 * @date 2019/8/5
 */
@RestController
public class BrowserSecurityController {

    public static final String HTML_END_SUFFIX = ".html";
    private Logger logger = LoggerFactory.getLogger(getClass());

    // 从RequestCache中拿到缓存在session中的请求
    private RequestCache requestCache = new HttpSessionRequestCache();

    private RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();

    @Autowired
    private ProviderSignInUtils providerSignInUtils;

    @Autowired
    private SecurityProperties securityProperties;

    /**
     * 当需要身份认证时，跳转到这里
     * @param request
     * @param response
     * @return
     */
    @RequestMapping(SecurityConstants.DEFAULT_UNAUTHENTICATION_URL)
    @ResponseStatus(code= HttpStatus.UNAUTHORIZED)
    public Response requireAuthentication(HttpServletRequest request, HttpServletResponse response) throws IOException {
        SavedRequest savedRequest = requestCache.getRequest(request, response);
        if (savedRequest != null) {
            String redirectUrl = savedRequest.getRedirectUrl();
            logger.info("引发跳转的请求是:{}", redirectUrl);
            if (StringUtils.endsWithIgnoreCase(redirectUrl, HTML_END_SUFFIX)) {
                // 让用户配置登录页面
                redirectStrategy.sendRedirect(request,response,securityProperties.getBrowser().getLoginPage());
            }
        }
        Response resp = new Response();
        resp.setErrorcode(ErrorCode.NO_AUTHENTICATION.value);
        resp.setValue(ErrorCode.NO_AUTHENTICATION.memo+"validMsg:"+"访问的服务需要身份认证，请引导用户到登录页");
        return resp;
    }

    /**
     * 展示在用户注册或者绑定的页面上使用
     * 在browser和app中都需要使用
     * 后面我们采用了默认注册的方式
     * @param request
     * @return
     */
    @GetMapping("/social/user")
    public Response getSocialUserInfo(HttpServletRequest request) {
        Response resp = new Response();
        ErrorCode result = ErrorCode.OK;
        SocialUserInfo socialUserInfo = null;
        try {
            socialUserInfo = new SocialUserInfo();
            Connection<?> connectionFromSession =
                    providerSignInUtils.getConnectionFromSession(new ServletWebRequest(request));
            socialUserInfo.setProviderId(connectionFromSession.getKey().getProviderId());
            socialUserInfo.setProviderUserId(connectionFromSession.getKey().getProviderUserId());
            socialUserInfo.setNickname(connectionFromSession.getDisplayName());
            socialUserInfo.setHeadImg(connectionFromSession.getImageUrl());
            resp.setData(socialUserInfo);
        } catch (Exception e) {
            result = ErrorCode.ERROR;
        }
        resp.setErrorcode(result.value);
        resp.setValue(result.memo);
        return resp;
    }
}
